package com.util.calculadoraip;

import java.util.regex.Pattern;

public class OperacoesIP {
	
	public String converterIP(String ip) {
		/* Dividi o IP em 4 octetos, converte para binario e junta novamente */		  
		String[] octeto = ip.split (Pattern.quote ("."));
		String bin = Integer.toBinaryString(Integer.parseInt(octeto[0]))+"."
				+ Integer.toBinaryString(Integer.parseInt(octeto[1]))+"."
				+ Integer.toBinaryString(Integer.parseInt(octeto[2]))+"."
				+ Integer.toBinaryString(Integer.parseInt(octeto[3]));
		/* Faz com que todos os bloco tenham 8 caracter */
		String[] octetoBin = bin.split (Pattern.quote ("."));
		String saida="";
		for(int i = 0; i < 4;i++){
			int t = 8 - octetoBin[i].length();
			for(int j = 0;j < t; j++){
				saida += "0";
			}
			saida += octetoBin[i]+".";
		}
		return saida.substring(0, saida.length()-1);
	}	
	
	public String reverterIP(String bin){
		/* Dividi o binario em 4 octetos, converte para decimal e junta novamente */
		String[] octeto = bin.split (Pattern.quote ("."));
		String ip = Integer.parseInt(octeto[0],2)+"."
				+ Integer.parseInt(octeto[1],2)+"."
				+ Integer.parseInt(octeto[2],2)+"."
				+ Integer.parseInt(octeto[3],2);		
		return ip;
	}
	/* gera a mascara */
	public String gerarMascara(int bit){
		int x = (int)bit/8;
		int y = 4 - x;
		int z = bit%8;						
		String saida="";
		int c= 0;
		
		/*for para preencher a parte inteira da mascara (255.255...) */
		for(int i = 0;i < x;i++){
			String bin="";
			for(int j = 0;j < 8;j++){
				bin +="1";
			}			
			saida += String.valueOf(Integer.parseInt(bin,2))+".";			
		}
		
		/*for para preencher a parte quebrada da mascara (...192.0) */
		for(int i = 0;i < y;i++){
			String bin="";
			for(int j = 0;j < 8;j++){
				if(c < z){
				bin +="1";
				}else{
					bin+=0;
				}
				c++;
			}			
			saida+=String.valueOf(Integer.parseInt(bin,2))+".";			
		}				
		return saida.substring(0, saida.length()-1);//retira o ponto final
	}
	/* Retorna o bit que gerou a mascara */
	public int reverterMascara(String mascara){
		String mascaraBin = converterIP(mascara);
		int c = 0;
		for(int i = 0;i < mascaraBin.length();i++){
			if(mascaraBin.charAt(i) == '1'){
				c++;
			}
		}
		return c;
	}
	/* gera o NetId */
	public String gerarNetId(String ip, String masc){
		String saida="";
		String[] octetoIp = ip.split (Pattern.quote ("."));
		String[] octetoMasc = masc.split (Pattern.quote ("."));
		for(int i = 0;i < 4;i++){
			if(octetoMasc[i].equals("255")){
				saida += octetoIp[i]+".";
			}else if(octetoMasc[i].equals("0")){
				saida += "0.";
			}else{	
				int aux = 256-Integer.parseInt(octetoMasc[i]);
				int result = (int)(Integer.parseInt(octetoIp[i]) / aux) * aux;
				saida += result+".";
			}
		}
		return saida.substring(0, saida.length()-1);//retira o ponto final
	}
	/* gera o Broadcast */
	public String gerarBroadcast(String netId, String masc){
		String saida="";
		String[] octetoIp = netId.split (Pattern.quote ("."));
		String[] octetoMasc = masc.split (Pattern.quote ("."));
		int aux=0;
		for(int i = 0;i < 4;i++){
			aux = 255 - Integer.parseInt(octetoMasc[i]) + Integer.parseInt(octetoIp[i]);
			saida += aux+".";
		}
		return saida.substring(0, saida.length()-1);//retira o ponto final
	}
	/* verifica se o ip eh valido */
	public int verificarValido(String ip, int bit){
		String m = gerarMascara(bit);
		String n = gerarNetId(ip, m);
		String b = gerarBroadcast(n, m);
		if(ip.equals(n)){
			return 0;//o ip eh o netId
		}else if(ip.equals(b)){
			return 1;//o ip eh broadcast
		}else{
			return 2;//o ip eh valido;
		}
	}
	/* verifica se o ip eh publico ou particular */
	public boolean isParticular(String ip) {
		String[] octeto = ip.split(Pattern.quote("."));
		if (octeto[0].equals("10") || (octeto[0] + octeto[1]).equals("192168")) {
			return true;
		}else if(Integer.parseInt(octeto[0]+octeto[1]) >= 17216 && Integer.parseInt(octeto[0]+octeto[1]) <= 17231 ){
			return true;
		}else {
			return false;
		}
	}
	/* calcula o total de ip na rede */
	public long calcularTotalIps(int bit){
		String m = converterIP(gerarMascara(bit));
		String aux = "";
		String[] octetoBin = m.split (Pattern.quote ("."));
		for(int i = 0; i < 4;i++){			
			aux += octetoBin[i];
		}
		int c=0;
		for(int i = 0;i < aux.length();i++){
			if(aux.charAt(i) == '0'){
				c++;
			}			
		}		
		return (long) Math.pow(2, c);
	}
	/* calcula o primeiro valido ip na rede */
	public String calcularPrimeiroIp(String ip, int bit){
		String[] octeto = gerarNetId(ip, gerarMascara(bit)).split(Pattern.quote("."));				
		return octeto[0] + "." 
				+ octeto[1] + "."
				+ octeto[2] + "."
				+ String.valueOf(Integer.parseInt(octeto[3]) + 1);
	}
	/* calcula o ultimo valido ip na rede */
	public String calcularUltimoIp(String ip, int bit){
		String m = gerarMascara(bit);
		String[] octeto = gerarBroadcast(gerarNetId(ip, m), m).split(Pattern.quote("."));				
		return octeto[0] + "." 
				+ octeto[1] + "."
				+ octeto[2] + "."
				+ String.valueOf(Integer.parseInt(octeto[3]) - 1);
	}
}
